home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
quintus
/
quintus0.lha
/
work
/
group_2.06.2
< prev
next >
Wrap
Text File
|
1992-04-03
|
16KB
|
432 lines
%%%
%%% version 2.04.8
%%% initial version
%%% version 2.05.1
%%% fixed assert_group_axiom so that it works when neither fixed_priority
%%% nor slidepriority is specified
%%% version 2.05.2
%%% don't rewrite clauses in group dection
%%% fixed bug in assert_group_properties
%%% version 2.05.3
%%% added support for Quintus Prolog
%%% version 2.05.4
%%% rewrite rewrite rules after asserting group rewrite rule
%%% version 2.05.5
%%% rewrite group axioms before asserting
%%% version 2.06.0
%%% rewrite rewrite rules only once during group detection
%%% version 2.06.1
%%% rewrite group rewrite rule before asserting
%%% rewrite replace rules
%%% version 2.06.2
%%% fixed assert_group_axiom/1 to work when priority_bound is not set
%%%
%%% This is the code for group dectection. A group with binary operation
%%% f(X,Y), inverse g(X), and identity e is deceted if the following clauses
%%% are asserted:
%%%
%%% f(f(X,Y),Z)=f(X,f(Y,Z)) associativity
%%% f(e,X)=X left identity
%%% f(g(X),X)=e left inverse
%%%
%%% or if the following clauses are asserted:
%%%
%%% f(f(X,Y),Z)=f(X,f(Y,Z)) associativity
%%% f(X,e)=X right identity
%%% f(X,g(X))=e right inverse
%%%
%%% Note that the binary operation, inverse, and identity can be any
%%% arbitrary term containing two, one, and zero distinct variables
%%% respectively.
%%%
%%% When a new group is detected, the following clauses are asserted if not
%%% already present:
%%%
%%% f(e,X)=X g(e)=e
%%% f(g(X),X)=e g(g(X))=X
%%% f(f(X,Y),Z)=f(X,f(Y,Z)) f(X,g(X))=e
%%% f(g(X),f(X,Y))=Y f(X,f(g(X),Y))=Y
%%% f(X,e)=X g(f(X,Y))=f(g(Y),g(X))
%%%
%%% The group axioms are rewritten before being asserted. If auto_orient is
%%% set, rewrite rules are asserted for each the above equations if not
%%% already present. If replacement is set, the following repeated replace
%%% rules with no context literals are also asserted if not already present:
%%%
%%% f(X,Y)=f(X,Z) --> Y=Z
%%% f(Y,X)=f(Z,X) --> Y=Z
%%% f(X,Y)=X --> Y=e
%%% f(Y,X)=X --> Y=e
%%% f(X,Y)=e --> Y=g(X)
%%% f(Y,X)=e --> Y=g(X)
%%%
%%% When an old group is detected, if the new inverse operation g'(x) differs
%%% from the old inverse operation g(x), the equation g'(x)=g(x) and its
%%% associated rewrite rule are asserted. If the new identity element e'
%%% differs from the old identity element e, the equation e'=e and its
%%% corresponding rewrite rule is asserted. Check_group_found then fails.
%%%
%%% Run_ground_detection checks for all possible groups.
%%%
run_group_detection :-
not(group_detection),
!.
run_group_detection :-
cputime(TT1),
find_groups,
(group_rewrite_rule_asserted -> (
abolish(group_rewrite_rule_asserted,0),
rewrite_rewrite_rules(1),
rewrite_replace_rules
); true),
cputime(TT2),
TT3 is TT2 - TT1,
write_line(5,'Group detection(s): ',TT3),
!.
%%%
%%% Find_groups finds all possible groups as follows:
%%% 1. For each asserted clause determine if it is the associativity axiom
%%% for some binary operation.
%%% 2. If a clause is the associativity axiom for some binary operation,
%%% determine if the additional group axioms are present for the binary
%%% operation.
%%% 3. If the additional group axioms are present, print a description of
%%% the group and assert the group properties.
%%%
%%% Note that new clauses are temporarily asserted as sent_G until all of
%%% existing clauses have been examined.
%%%
find_groups :-
sent_C(cl(_,_,by([S=T],V,V,_,_),_,_,_,_,_,_)),
is_associativity_axiom(S=T,Binop),
is_group(Binop,Inverse,Identity,Axiom_type),
check_group_found(Binop,Inverse,Identity),
print_group_description(Binop,Inverse,Identity),
assert_group_properties(Binop,Inverse,Identity,Axiom_type),
fail.
find_groups :-
retract(sent_G(C)),
assertz(sent_C(C)),
fail.
find_groups.
%%%
%%% Is_associativity_axiom determines if an equation is an associativity axiom.
%%% If the equation is an associativity axiom, the binary operation of the
%%% associativity axiom is returned as a list of three terms: the binary
%%% operation, its first argument, and its second operation.
%%%
is_associativity_axiom(S=T,Binop) :-
list_vars(S=T,[V1,V2,V3]),
get_subterms(S,Ss),
is_associativity_axiom_1(Ss,S=T,Binop),
!.
is_associativity_axiom_1([Op|_],S=T,[Op,X,Y]) :-
list_vars(Op,[X,Y]),
build_associativity_axiom([Op,X,Y],Assoc_axiom),
duplicate_clauses([S=T],[Assoc_axiom]),
!.
is_associativity_axiom_1([Op|_],S=T,[Op,Y,X]) :-
list_vars(Op,[X,Y]),
build_associativity_axiom([Op,Y,X],Assoc_axiom),
duplicate_clauses([S=T],[Assoc_axiom]),
!.
is_associativity_axiom_1([_|Ss],S=T,Binop) :-
!,
is_associativity_axiom_1(Ss,S=T,Binop).
%%%
%%% Build_associativity_axiom creates the associativity axiom for a specified
%%% binary operation.
%%%
build_associativity_axiom([Op,X,Y],S=T) :-
asserta(baa_temp(Op,X,Y)),
baa_temp(S,Dummy1,V3),
baa_temp(Dummy1,V1,V2),
baa_temp(T,V1,Dummy2),
baa_temp(Dummy2,V2,V3),
retract(baa_temp(_,_,_)),
!.
%%%
%%% Is_group determines if the group axioms for an associativity binary
%%% operation are present. If the group axioms are present, the inverse
%%% operation of the group, the identity element of the group, and the type
%%% group axioms found are returned. The inverse operation is returned as
%%% a list of two terms: the inverse operation and its arguement. The
%%% identity element is returned as a list of one term: the identity element.
%%% The axioms type is returned as either l, indicating that the left inverse
%%% and left identity axioms were used, or r, indicating that the right inverse
%%% and right identity axioms were used.
%%%
is_group([Op,X,Y],[Inv,Z],[Ident],Axiom_type) :-
asserta(ig_temp(Op,X,Y)),
is_group_1([Inv,Z],[Ident],Axiom_type).
is_group(_,_,_,_) :-
retract(ig_temp(_,_,_)),
!,
fail.
is_group_1([Inv,Z],[Ident],l) :-
ig_temp(S1,Inv,Z),
sent_C(cl(_,_,by([S1=Ident],V11,V12,_,_),_,_,_,_,_,_)),
unify_lists(V11,V12),
var(Z),
list_vars(Inv,[Z]),
list_vars(Ident,[]),
sent_C(cl(_,_,by([S2=A],V21,V22,_,_),_,_,_,_,_,_)),
unify_lists(V21,V22),
var(A).
is_group_1([Inv,Z],[Ident],l) :-
ig_temp(S1,Z,Inv),
sent_C(cl(_,_,by([S1=Ident],V11,V12,_,_),_,_,_,_,_,_)),
unify_lists(V11,V12),
var(Z),
list_vars(Inv,[Z]),
list_vars(Ident,[]),
ig_temp(S2,A,Ident),
sent_C(cl(_,_,by([S2=A],V21,V22,_,_),_,_,_,_,_,_)),
unify_lists(V21,V22),
var(A).
%%%
%%% Check_group_found determines if a group has already been found during the
%%% current session. If it has not, check_group_found saves a description of
%%% the group. Otherwise, if the new inverse operation g'(x) differs from the
%%% old inverse operation g(x), the equation g'(x)=g(x) and its associated
%%% rewrite rule are asserted. If the new identity element e' differs from the
%%% old identity element e, the equation e'=e and its corresponding rewrite
%%% rule is asserted. Check_group_found then fails.
%%%
check_group_found([Binop,X,Y],[Inverse,Z],[Identity]) :-
const_list([X,Y,Z|_]),
group_descr([Binop,X,Y],[Inverse,Z],[Identity]),
!,
fail.
check_group_found([Binop,X,Y],[Inverse1,Z],[Identity1]) :-
assert(cgf_temp([Binop,X,Y])),
const_list([X,Y|_]),
group_descr([Binop,X,Y],[Inverse2,Z],[Identity2]),
cgf_temp(Binop1),
print_group_description(Binop1,[Inverse1,Z],[Identity1]),
assert(group_descr(Binop1,[Inverse1,Z],[Identity1])),
check_group_found_1(Inverse1,Inverse2),
check_group_found_2(Identity1,Identity2),
retract(cgf_temp(_)),
!,
fail.
check_group_found(Binop,Inverse,Identity) :-
retract(cgf_temp(_)),
assert(group_descr(Binop,Inverse,Identity)),
!.
check_group_found_1(Inverse1,Inverse2) :-
Inverse1\==Inverse2,
assert_group_axiom(Inverse2=Inverse1),
!.
check_group_found_1(_,_).
check_group_found_2(Identity1,Identity2) :-
Identity1\==Identity2,
assert_group_axiom(Identity2=Identity1),
!.
check_group_found_2(_,_).
%%%
%%% Print_group_description prints a description of a group.
%%%
print_group_description(Binop,Inverse,[Identity]) :-
write_line(10,'*** Group detected ***'),
not(not(print_group_description_1(Binop))),
not(not(print_group_description_2(Inverse))),
write_line(15,'Identity: ',Identity),
!.
print_group_description_1([Op,'X','Y']) :-
write_line(15,'Binary operation: ',Op),
!.
print_group_description_2([Op,'X']) :-
write_line(15,'Inverse: ',Op),
!.
%%%
%%% Assert_group_properties asserts the group properties: equations, rewrite
%%% rules, and replace rules.
%%%
assert_group_properties([Binop,X,Y],[Inverse,Z],[Identity],Axiom_type) :-
assert(agp_binop(Binop,X,Y)),
assert(agp_inverse(Inverse,Z)),
assert(agp_identity(Identity)),
assert_group_properties_1(Axiom_type),
retract(agp_binop(_,_,_)),
retract(agp_inverse(_,_)),
retract(agp_identity(_)),
!.
assert_group_properties_1(l) :-
assert_right_group_axioms,
assert_other_group_axioms,
assert_group_replace_rules,
!.
assert_group_properties_1(r) :-
assert_left_group_axioms,
assert_other_group_axioms,
assert_group_replace_rules,
!.
%%%
%%% Assert_left_group_axioms asserts the left inverse and left identity
%%% axioms and corresponding rewrite rules for a specified group.
%%% Assert_right_group_axioms assumes that the group operations have been
%%% asserted as agp_binop, agp_inverse, and agp_indentity.
%%%
assert_left_group_axioms :-
agp_binop(S1,Temp1,X),
agp_inverse(Temp1,X),
agp_identity(Identity),
assert_group_axiom(S1=Identity),
agp_binop(S2,Identity,X),
assert_group_axiom(S2=X),
!.
%%%
%%% Assert_right_group_axioms asserts the right inverse and right identity
%%% axioms and corresponding rewrite rules for a specified group.
%%% Assert_right_group_axioms assumes that the group operations have been
%%% asserted as agp_binop, agp_inverse, and agp_indentity.
%%%
assert_right_group_axioms :-
agp_binop(S1,X,Temp1),
agp_inverse(Temp1,X),
agp_identity(Identity),
assert_group_axiom(S1=Identity),
agp_binop(S2,X,Identity),
assert_group_axiom(S2=X),
!.
%%%
%%% Assert_other_group_axioms asserts the following axioms and corresponding
%%% rewrite rules for a specified group:
%%% f(g(X),f(X,Y))=Y
%%% g(e)=e
%%% g(g(X))=X
%%% f(X,f(g(X),Y))=Y
%%% g(f(X,Y))=f(g(Y),g(X))
%%% The group axioms are rewritten before being asserted.
%%% Assert_other_group_axioms assumes that the group operations have been
%%% asserted as agp_binop, agp_inverse, and agp_indentity.
%%%
assert_other_group_axioms :-
agp_binop(S1,Temp1,Temp2),
agp_inverse(Temp1,X),
agp_binop(Temp2,X,Y),
assert_group_axiom(S1=Y),
agp_inverse(S2,Identity),
agp_identity(Identity),
assert_group_axiom(S2=Identity),
agp_inverse(S3,Temp3),
agp_inverse(Temp3,X),
assert_group_axiom(S3=X),
agp_binop(S4,X,Temp4),
agp_binop(Temp4,Temp5,Y),
agp_inverse(Temp5,X),
assert_group_axiom(S4=Y),
agp_inverse(S5,Temp6),
agp_binop(Temp6,X,Y),
agp_binop(T5,Temp7,Temp8),
agp_inverse(Temp7,Y),
agp_inverse(Temp8,X),
assert_group_axiom(S5=T5),
!.
%%%
%%% Assert_group_axiom asserts a group axiom if the axiom is not already
%%% asserted and its priority is not too large. Also, assert_group_axiom
%%% asserts the corresponding rewrite rule if the equation is asserted and
%%% auto_orient is set. Rewrite group axiom before asserting it.
%%%
assert_group_axiom(Axiom) :-
(constrained_rewriting -> (
(restricted_rewrite -> (
abolish(restricted_rewrite,0),
rewrite_clause_with_constraint([Axiom],_,_,[],Cts),
assert(restricted_rewrite)
); (
rewrite_clause_with_constraint([Axiom],_,_,[],Cts)
)),
assert_group_axiom_1(Cts)
); (
(restricted_rewrite -> (
abolish(restricted_rewrite,0),
rewrite_clause_np([Axiom],_,_,0,[Axiom1],_),
assert(restricted_rewrite)
); (
rewrite_clause_np([Axiom],_,_,0,[Axiom1],_)
)),
assert_group_axiom_2([Axiom1])
)).
assert_group_axiom_1([]) :- !.
assert_group_axiom_1([[Axiom,_,_]|Cts]) :-
assert_group_axiom_2(Axiom),
assert_group_axiom_1(Cts).
assert_group_axiom_2([S=T]) :-
vars_tail([S=T],V),
clause_size([S=T],CSize),
(not(duplicate_clause_C(CSize,[S=T],V)) -> (
linearize_term([S=T],C,V1,V2),
vars_literals([S=T],W),
compute_V_lits(W,0,NLits),
set_user_support(C,Sup1),
set_sr_status(Sup1,C,Sp,Ds),
list_of_Ns(C,0,Dis),
calculate_priority_clause(C,Sp,Ds,Pr),
((not(priority_bound(_));
(priority_bound(PrioBound),check_prioritybound(Pr,PrioBound))) -> (
assertz(sent_G(cl(CSize,NLits,by(C,V1,V2,V,W),0,Sp,Ds,0,Dis,Pr))),
generate_rewrite_rule([S=T],F),
(F==1 -> (
assert_once(group_rewrite_rule_asserted)
); true)
); true)
); true).
%%%
%%% If replacement is set, assert_group_replace_rules asserts the following
%%% repeated replace rules with no context literals:
%%% f(X,Y)=f(X,Z) --> Y=Z
%%% f(Y,X)=f(Z,X) --> Y=Z
%%% f(X,Y)=X --> Y=e
%%% f(Y,X)=X --> Y=e
%%% f(X,Y)=e --> Y=g(X)
%%% f(Y,X)=e --> Y=g(X)
%%% Assert_group_replace_rules assumes that the group operations have been
%%% asserted as agp_binop, agp_inverse, and agp_indentity.
%%%
assert_group_replace_rules :-
replacement,
agp_binop(S1,X,Y),
agp_binop(T1,X,Z),
assert_group_replace_rule(S1=T1,Y=Z),
agp_binop(S2,Y,X),
agp_binop(T2,Z,X),
assert_group_replace_rule(S2=T2,Y=Z),
agp_identity(Identity),
assert_group_replace_rule(S1=X,Y=Identity),
assert_group_replace_rule(S2=X,Y=Identity),
agp_inverse(T3,X),
assert_group_replace_rule(S1=Identity,Y=T3),
assert_group_replace_rule(S2=Identity,Y=T3),
!.
assert_group_replace_rules.
%%%
%%% Assert_group_replace_rule asserts a single repeated replace rule with no
%%% context literals for a group.
%%%
assert_group_replace_rule(L1,L2) :-
negate(L1,L1n),
vars_tail([L1n,L2],V),
not(duplicate_repeated_replace_rule([L1n,L2],V)),
vars_literals([L1n,L2],W),
assertz(replace_rule_1([L1n,L2],V,W,[1,0],[0,0])),
!.
assert_group_replace_rule(_,_).